package com.glela.common.verify;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

public class Validation {
	private List<Valid> validList;

	public Validation() {
		validList = new ArrayList<Valid>();
	}

	public Validation(List<Valid> validList) {
		this.validList = validList;
	}

	public Validation addValid(Valid valid) {
		validList.add(valid);
		return this;
	}

	public Validation addValid(String key, Object paramValue, String rules) {
		validList.add(new Valid(key, paramValue, rules));
		return this;
	}

	public List<Valid> getValidList() {
		return validList;
	}

	public void setValidList(List<Valid> validList) {
		this.validList = validList;
	}

	public String run(HttpServletRequest request) {
		for (Valid valid : validList) {
			String[] rules = this.getSpliteRules(valid.getRules());
			for (String rule : rules) {
				Object ruleValue = this.getRuleValue(rule);
				String msg = null;
				String paramValue = valid.getParamValue() == null ? null : valid.getParamValue().toString().trim();
				if (rule.startsWith("defaultValue")) {
					if (paramValue == null) {
						valid.setParamValue(ruleValue);
						request.setAttribute(valid.getKey(), ruleValue);
					}
				} else if (ruleValue == null) {
					try {
						msg = (String) ValidationHandle.class.getMethod(rule, String.class, String.class).invoke(null, valid.getKey(), paramValue);
					} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
						e.printStackTrace();
					}
				} else {
					try {
						msg = (String) ValidationHandle.class.getMethod(this.getRuleMethod(rule), String.class, String.class, String.class).invoke(null, valid.getKey(), paramValue, ruleValue);
					} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
						e.printStackTrace();
					}
				}
				if (msg != null) {
					return msg;
				}
			}
		}
		return null;
	}

	public String run() {
		for (Valid valid : validList) {
			String[] rules = this.getSpliteRules(valid.getRules());
			for (String rule : rules) {
				Object ruleValue = this.getRuleValue(rule);
				String msg = null;
				String paramValue = valid.getParamValue() == null ? null : valid.getParamValue().toString().trim();
				if (ruleValue == null) {
					try {
						msg = (String) ValidationHandle.class.getMethod(rule, String.class, String.class).invoke(null, valid.getKey(), paramValue);
					} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
						e.printStackTrace();
					}
				} else {
					try {
						msg = (String) ValidationHandle.class.getMethod(this.getRuleMethod(rule), String.class, String.class, String.class).invoke(null, valid.getKey(), paramValue, ruleValue);
					} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
						e.printStackTrace();
					}
				}
				if (msg != null) {
					return msg;
				}
			}
		}
		return null;
	}

	private String getRuleMethod(String rule) {
		return rule.substring(0, rule.indexOf("["));
	}

	private String[] getSpliteRules(String rules) {
		return rules.split("\\|");
	}

	private Object getRuleValue(String rule) {
		Pattern pattern = Pattern.compile("\\[(.*?)\\]");
		Matcher matcher = pattern.matcher(rule);
		if (matcher.find()) {
			return matcher.group(1);
		}
		return null;
	}
}
